<template>
  <div class="module-layout view-module-design">
    <je-panel v-bind="options">
      <template #default>
        <div :id="viewDesignId" class="diagramContainer">
          <div v-if="designTableDatas.length <= 0" class="no-design-box"
            >请点击引入资源表进行编辑视图</div
          >
          <!-- <div v-else>{{ designTableDatas }}</div> -->
          <design-table
            v-for="data in designTableDatas"
            :key="data.tableId + data.sourceCode"
            :tabel-datas="data"
            :plumb-ins="plumbIns"
            class="item"
            @monitorDelete="monitorDelete"
            @checkChange="checkChange"
          ></design-table>
        </div>
      </template>
      <template v-if="false" #bottom>
        <je-tabs v-model:activeKey="configActiveKey">
          <je-tab-pane :key="relevancyConfig.code" :tab="relevancyConfig.name" style="height: 100%">
            <design-connect
              :concern-datas="concernDatas"
              @getConcernTable="getConcernTable"
              @changeLine="changeLine"
            />
          </je-tab-pane>
          <je-tab-pane :key="searchConfig.code" :tab="searchConfig.name" style="height: 100%">
            <design-query />
          </je-tab-pane>
        </je-tabs>
      </template>
    </je-panel>
  </div>
</template>

<script>
  import { defineComponent, reactive, toRefs, toRaw, ref, onMounted, nextTick, watch } from 'vue';
  import { Panel, Tabs, Modal } from '@jecloud/ui';
  import { jsPlumb } from 'jsplumb';
  import DesignTable from '@/views/data-source/source-view/components/design-table.vue';
  import DesignConnect from '@/views/data-source/source-view/components/design-connect.vue';
  import DesignQuery from '@/views/data-source/source-view/components/design-query.vue';
  import { VIEW_DESIGN_RELEVANCY_DESIGN, VIEW_DESIGN_SEARCH_CONFIG } from '@/helper/constant';
  import { useSourceStore } from '@/store/source-store';
  import { updateSourceAndModule, saveSourceTabalPosition } from '@/api/index';
  import VueEvent from '@/helper/event';
  import { SOURCE_RELOAD_TREE } from '@/helper/constant';
  export default defineComponent({
    name: 'SourceViewDesign',
    components: {
      JePanel: Panel,
      JeTabs: Tabs,
      JeTabPane: Tabs.TabPane,
      DesignTable,
      DesignConnect,
      DesignQuery,
    },
    props: {
      designDatas: {
        type: Object,
        requied: true,
        default: () => {
          return {};
        },
      },
      concernDatas: {
        type: Object,
        requied: true,
        default: () => {
          return {};
        },
      },
    },
    emits: ['chageCheckData', 'changeTableData', 'deleteConcernTableData'],
    setup(props, { emit }) {
      const sourceStore = useSourceStore(); //数据源全局状态
      const curSourceCode = sourceStore.getSourceCode();
      const plumbIns = ref(jsPlumb.getInstance());
      const state = reactive({
        options: {
          left: {
            size: 210,
            maxSize: 230,
            minSize: 210,
            split: true,
            collapsible: true,
            collapsed: false,
            style: { borderRight: '1px solid #ecedf0', borderBottom: '1px solid #ecedf0' },
          },
          bottom: { size: 300, split: false },
        },
        treeData: [], //数据表结构树
        designTableDatas: [], //选择的tabel数据 props.tableData
        relevancyConfig: VIEW_DESIGN_RELEVANCY_DESIGN, //设计视图-关联设计
        searchConfig: VIEW_DESIGN_SEARCH_CONFIG, //设计视图-查询配置
        configActiveKey: VIEW_DESIGN_RELEVANCY_DESIGN.code, //视图设计默认tab-关联设计
        // concernDatas: {
        //   //关联设计对应选择数据
        //   selectDatas: [], //下拉框数据
        //   tabelData: [],
        // },
        //关联设计对应选择数据
        concernDatas: props.concernDatas,
        viewDesignId: 'plumbIns' + curSourceCode,
        sourceCode: curSourceCode,
      });
      const methods = {
        showPlumb() {
          //初始化jsplumb插件
          plumbIns.value.ready(() => {
            //默认设置
            plumbIns.value.importDefaults({
              PaintStyle: { stroke: '#909399', strokeWidth: 2 },
              Connector: ['Straight'],
              Container: state.viewDesignId, //选择器id
              Endpoint: 'Blank',
              EndpointStyle: { radius: 0.11, fill: '#999' },
              ConnectionsDetachable: false, // 再次拖动时不取消选择
              maxConnections: 1,
              uniqueEndpoint: true,
              Anchor: [
                'Left',
                'Right',
                'Top',
                'Bottom',
                [0.3, 0, 0, -1],
                [0.7, 0, 0, -1],
                [0.3, 1, 0, 1],
                [0.7, 1, 0, 1],
              ],
            });
          });
        },
        addViewTable(node) {
          //将选择的表添加到视图中
          //判断table是否存在
          let flag = true;
          for (let index = 0; index < state.designTableDatas.length; index++) {
            if (state.designTableDatas[index].tableId == node.id) {
              flag = false;
              return flag;
            }
          }
          if (flag) {
            let iconCls = 'jeicon jeicon-table';
            if (node.nodeInfo == 'TREE') {
              iconCls = 'jeicon jeicon-treetable';
            } else if (node.nodeInfo == 'VIEW') {
              iconCls = 'jeicon jeicon-process';
            }
            state.designTableDatas.push({
              tableId: node.id,
              tableCode: node.code,
              tableName: node.text,
              iconCls,
              selectCode: [],
            });
            // emit('changeDatas', 'concernSelectData', {
            //   tableCode: node.code,
            //   tableId: node.id,
            //   tableName: node.text,
            //   value: node.code,
            //   label: node.text,
            // });
            methods.setDeisgnData(state.designTableDatas);
            let selectData = {
              tableCode: node.code,
              tableId: node.id,
              tableName: node.text,
              value: node.code,
              label: node.text,
            };
            state.concernDatas.selectDatas.push(selectData);
            emit('changeTableData', state.concernDatas);
            //拖拽
            nextTick(() => {
              document.getElementById(node.id + state.sourceCode).style.left =
                (state.designTableDatas.length - 1) * 40 + 5 + 'px';
              document.getElementById(node.id + state.sourceCode).style.top = '10px';
              plumbIns.value.draggable(node.id + state.sourceCode, {
                containment: state.viewDesignId,
                stop: function (e) {
                  // 拖拽后改变位置,修改本地数据
                  methods.saveRealLocation(node.id, e.pos);
                },
              });
            });
          }
        },
        checkChange(obj, records) {
          //监听子组件的design-table列选中状态
          emit('chageCheckData', obj, records);
        },
        monitorDelete(tableId) {
          //监听删除table面板
          //删除视图设计的table
          state.designTableDatas.forEach((item, index) => {
            if (item.tableId == tableId) {
              state.designTableDatas.splice(index, 1);
            }
          });
          methods.setDeisgnData(state.designTableDatas);
          //删除下拉框的数据
          // emit('changeDatas', 'delConcernSelectData', {
          //   tableId: tableId,
          // });
          state.concernDatas.selectDatas.forEach((item, index) => {
            if (item.tableId == tableId) {
              state.concernDatas.selectDatas.splice(index, 1);
            }
          });
          //删除关系设置的数据
          emit('deleteConcernTableData', tableId);
          emit('changeTableData', state.concernDatas);
        },
        getConcernTable(obj) {
          //关系设置table对象
          state.concernDatas.tableObj = obj;
        },
        changeLine(row) {
          //监听关系设置的数据变化,改变连线,jsplumb插件修改连线
          //添加连线
          if (row.isDispalyLine) {
            const connections = plumbIns.value.getAllConnections();
            for (let i in connections) {
              if (
                connections[i].sourceId === row.mainTableId &&
                connections[i].targetId === row.targetTableId
              ) {
                // 删除相匹配的线
                plumbIns.value.deleteConnection(connections[i]); // deleteConnection(@) 删除链接线  @线对象
              }
            }
            let overlays = [];
            if (row.mainIdentifier == '1' && row.targetIdentifier == 'n') {
              if (row.mainTableId == row.targetTableId) {
                overlays = [
                  ['Label', { label: '1:n', location: -40 }],
                  ['Arrow', { width: 10, length: 10, location: 1, direction: 1 }],
                ];
              } else {
                overlays = [
                  ['Label', { label: '1:n' }],
                  ['Arrow', { width: 10, length: 10, location: 1, direction: 1 }],
                ];
              }
            } else if (row.mainIdentifier == 'n' && row.targetIdentifier == '1') {
              if (row.mainTableId == row.targetTableId) {
                overlays = [
                  ['Label', { label: 'n:1', location: -40 }],
                  ['Arrow', { width: 10, length: 10, location: 1, direction: 1 }],
                ];
              } else {
                overlays = [
                  ['Label', { label: 'n:1' }],
                  ['Arrow', { width: 10, length: 10, location: 0, direction: -1 }],
                ];
              }
            } else if (row.mainIdentifier == 'n' && row.targetIdentifier == 'n') {
              if (row.mainTableId == row.targetTableId) {
                overlays = [
                  ['Label', { label: 'n:n', location: -40 }],
                  ['Arrow', { width: 10, length: 10, location: 1, direction: 1 }],
                ];
              } else {
                overlays = [
                  ['Label', { label: 'n:n' }],
                  ['Arrow', { width: 10, length: 10, location: 1, direction: 1 }],
                  ['Arrow', { width: 10, length: 10, location: 0, direction: -1 }],
                ];
              }
            } else if (row.mainIdentifier == '1' && row.targetIdentifier == '1') {
              if (row.mainTableId == row.targetTableId) {
                overlays = [['Label', { label: '1:1', location: -40 }]];
              } else {
                overlays = [['Label', { label: '1:1' }]];
              }
            }
            if (row.mainTableId == row.targetTableId) {
              plumbIns.value.connect({
                // 对应上述基本概念
                source: row.mainTableId,
                target: row.targetTableId,
                connector: ['StateMachine'],
                overlays: overlays,
              });
            } else {
              plumbIns.value.connect({
                // 对应上述基本概念
                source: row.mainTableId,
                target: row.targetTableId,
                overlays: overlays,
              });
            }
            //删除连线
          } else {
            const connections = plumbIns.value.getAllConnections();
            for (let i in connections) {
              if (
                connections[i].sourceId === row.mainTableId &&
                connections[i].targetId === row.targetTableId
              ) {
                // 删除相匹配的线
                plumbIns.value.deleteConnection(connections[i]); // deleteConnection(@) 删除链接线  @线对象
              }
            }
          }
        },
        //设置关联视图
        setDeisgnData(designData) {
          const curSourceCode = sourceStore.getSourceCode();
          const curSourceData = sourceStore.getSourceDataByCode(curSourceCode);
          curSourceData.DATASOURCE_BASE_TABLE = JSON.stringify(designData);
        },
        //保存图表实时位置
        saveRealLocation(tableId, position) {
          const curSourceCode = sourceStore.getSourceCode();
          const curSourceData = sourceStore.getSourceDataByCode(curSourceCode);
          const tableList = JSON.parse(curSourceData.DATASOURCE_BASE_TABLE);
          tableList.forEach((item) => {
            if (item.tableId == tableId) {
              item.left = position[0];
              item.top = position[1];
            }
          });
          //保存图表移动位置
          const positionParam = {
            tableCode: 'JE_CORE_DATASOURCE',
            JE_CORE_DATASOURCE_ID: curSourceData.JE_CORE_DATASOURCE_ID,
            DATASOURCE_BASE_TABLE: JSON.stringify(tableList),
          };
          saveSourceTabalPosition(positionParam).then((res) => {
            if (!res.success) {
              Modal.alert(res.message, 'error');
            } else {
              curSourceData.DATASOURCE_BASE_TABLE = JSON.stringify(tableList);
              sourceStore.setSourceDataByCode(curSourceCode, curSourceData);
            }
          });
        },
      };
      //回显连线
      watch(
        () => props.designDatas.lineinfo,
        (newVal) => {
          nextTick(() => {
            newVal.forEach((item) => {
              methods.changeLine(item);
            });
          });
        },
        { deep: true },
      );
      //回显表格数据
      watch(
        () => props.designDatas.tableDatas,
        (newVal) => {
          state.designTableDatas = newVal;
          const curSourceCode = sourceStore.getSourceCode();
          const curSourceData = sourceStore.getSourceDataByCode(curSourceCode);
          let positionTabelList = [];
          if (curSourceData.DATASOURCE_BASE_TABLE) {
            positionTabelList = JSON.parse(curSourceData.DATASOURCE_BASE_TABLE);
          }
          nextTick(() => {
            const temTableData = toRaw(newVal);
            //兼容之前的数据
            if (positionTabelList.length > 0) {
              temTableData.forEach((item, index) => {
                positionTabelList.forEach((positionItem) => {
                  if (item.tableId == positionItem.tableId) {
                    item.sourceCode = item.sourceCode ? item.sourceCode : curSourceCode;
                    document.getElementById(item.tableId + item.sourceCode).style.left =
                      positionItem.left + 'px';
                    document.getElementById(item.tableId + item.sourceCode).style.top =
                      positionItem.top + 'px';
                    plumbIns.value.draggable(item.tableId + item.sourceCode, {
                      containment: state.viewDesignId,
                      stop: function (e) {
                        // 拖拽后改变位置,修改本地数据
                        methods.saveRealLocation(item.tableId, e.pos);
                      },
                    });
                  }
                });
              });
            } else {
              temTableData.forEach((item, index) => {
                item.sourceCode = item.sourceCode ? item.sourceCode : curSourceCode;
                document.getElementById(item.tableId + item.sourceCode).style.left =
                  item.left + 'px';
                document.getElementById(item.tableId + item.sourceCode).style.top = item.top + 'px';
                plumbIns.value.draggable(item.tableId + item.sourceCode, {
                  containment: state.viewDesignId,
                  stop: function (e) {
                    // 拖拽后改变位置,修改本地数据
                    methods.saveRealLocation(item.tableId, e.pos);
                  },
                });
              });
            }
          });
        },
        { deep: true },
      );
      onMounted(() => {
        nextTick(() => {
          methods.showPlumb();
        });
      });
      return {
        plumbIns,
        ...toRefs(state),
        ...methods,
      };
    },
  });
</script>
<style scoped lang="less">
  .module-layout {
    width: 100%;
    height: 100%;
    .no-design-box {
      position: absolute;
      top: 30%;
      left: 25%;
      font-size: 18px;
      color: #a9aba9;
    }
    .searchInput {
      height: 40px;
      border-color: #e6e6e6 !important;
      border-radius: 0;
    }
    .diagramContainer {
      position: relative;
      height: 150% !important;
      width: 150% !important;
    }
    .item {
      position: absolute;
      height: 500px;
      width: 400px;
      border-top: 1px solid #e6e6e6;
      border-bottom: 1px solid #e6e6e6;
      z-index: 10;
    }
    .design-title {
      height: 40px;
      background: #f7f9fc;
      line-height: 40px;
      font-size: 14px;
      padding: 0 16px;
      color: #3265f5;
    }
    .design-title.top {
      border-bottom: 1px solid #e6e6e6;
      border-top: 1px solid #e6e6e6;
    }
    .design-table {
      height: 100%;
    }
    .beforesign {
      position: relative;
      display: inline-block;
      height: 4px;
      &::before {
        content: '';
        display: inline-block;
        width: 4px;
        height: 4px;
        background: #d70000;
        position: absolute;
        top: -7px;
        left: -6px;
      }
    }
    .aftersign {
      position: relative;
      display: inline-block;
      height: 4px;
      &::after {
        content: '';
        display: inline-block;
        width: 4px;
        height: 4px;
        background: #006ed7;
        position: absolute;
        bottom: -1px;
        left: -6px;
      }
    }
    .treebottom-context {
      font-size: 14px;
      height: 32px;
      line-height: 32px;
      text-align: center;
      margin: 10px;
      .context {
        height: 32px;
        border: 1px solid #a8d09d;
        background: #eff9f2;
        color: #36761f;
      }
    }
  }
</style>
